﻿//
//  ValidationUtils
//
//  Created by Hatch on 2008-07-29.
//

import mx.utils.Delegate;
import mx.events.EventDispatcher;

class com.hatch.audio.Metronome
{
	private var _tempo:Number;
	private var _beats:Number;
	private var	_beat:Number;
	private var	_timer:Number;
	private var _downBeat:Boolean;
	private var _lapNum:Number;
	private var _active:Boolean;
	private var _dispatcher:EventDispatcher;
	
	
	function Metronome( beats:Number, tempo:Number )	//beats:int = 4, tempo:Number = 120
	{
		_beats = beats;
		_beat = 0;
		_tempo = tempo;
		_downBeat = true;
		_lapNum = 1;
		_active = false;
		_dispatcher = new EventDispatcher();
	}
	
	public function start():Void
	{
		trace( "Metronome :: start()" );
		_active = true;
		_timer = setInterval( Delegate.create( this,  tick), _tempo/2 );
	}
	
	public function stop():Void
	{
		_active = false;
		clearInterval(_timer);
	}
	
	public function reset():Void
	{
		trace( "Metronome :: reset()");
		_active = false;
		clearInterval(_timer);
		_lapNum = 1;
		_beat = 0;
		_downBeat = true;
	}
	
	private function tick():Void
	{
		
		//alternate between down/up beat dispatches
		if( _downBeat )
		{
			//dispatch beginning of loop
			if( _beat == 0 )
			{
				_dispatcher.dispatchEvent( { type:"lapStart", target:this, lap: _lapNum++  } );
			}
			if( !_active ){ return; }
			//trace( "Metronome :: tick() _beat == " + _beat);
			_dispatcher.dispatchEvent( { type:"beat_down", target:this, beat: _beat } );
			_beat = ++_beat % _beats;
			_downBeat = false;
		}
		else
		{
			_dispatcher.dispatchEvent( { type:"beat_up", target:this, beat: _beat } );
			_downBeat = true;
		}	
	}
	

	
	public function setTempo( tempo:Number ):Void
	{
		_tempo = tempo;
		
		clearInterval(_timer);
		_timer = setInterval( Delegate.create( this,  tick), _timer );
	}
	
	public function addEventListener(type:String, handler:Object):Void
	{
		_dispatcher.addEventListener(type, handler);
	}
	
	public function get prevBeat():Number
	{
		return (_beat == 0) ? _beats-1 : _beat-1;
	}
}